/*
   Communication Library v1.0
   this library used libev
*/


#ifndef __SERVER_H__
#define __SERVER_H__

#include "ev.h"
#include "queue.h"
#include "hash.h"

typedef struct connection_t {
    int  sfd;
    char clientip[16];
    int  port;
    char *readbuffer;
    char *writebuffer;
    int rlastpos;
    int wlastpos;
    int rbuffersize;
    int wbuffersize;
    pthread_mutex_t conn_locker;
    struct ev_io io_watcher;
    void *userdata;
}CONN_ITEM;

typedef struct pending_queue_item {
    int sfd;
    char clientip[16];
    int port;
    TAILQ_ENTRY(pending_queue_item) entries;
}PQ_ITEM;

typedef void (*init_user_data)(CONN_ITEM *item);
typedef void (*free_user_data)(CONN_ITEM *item);
typedef int (*network_data_callback)(struct ev_loop *loop,CONN_ITEM *item,void *data,int len);
typedef void (*network_error_callback)(CONN_ITEM *item);


typedef struct {
    pthread_t thread_id;                 /* unique ID of this thread */
    struct ev_loop *loop;                /* libev loop this thread uses */
    struct ev_async async_watcher;       /* async watcher for new connect */
    int ifexit;                          /*exit flag*/
    TAILQ_HEAD(,PQ_ITEM) new_conn_queue;
    pthread_mutex_t new_conn_queue_locker;
    TAILQ_HEAD(,PQ_ITEM) pending_queue;
    pthread_mutex_t pending_queue_locker;
    pthread_cond_t pending_queue_cond;
    hashtable *connlist;   
    pthread_mutex_t connlist_locker;
} WORK_THREAD;


typedef struct {
    pthread_t thread_id;         /* unique ID of this thread */
    struct ev_loop *loop;     /* libev loop this thread uses */
    struct ev_io accept_watcher;   /* accept watcher for new connect */
    struct ev_signal signal_watcher;
    init_user_data pfn_init_user_data;
    free_user_data pfn_free_user_data;
    network_data_callback pfn_network_data_callback;
    network_error_callback pfn_network_error_callback;
    short port;
    int workthread_num;
    int rbuffersize;
    int wbuffersize;
    int maxconns;
}SERVERINFO;

enum {
 T_PORT = 1,
 T_WORKTHREAD_NUM,         
 T_READBUFFERSIZE, 
 T_WRITEBUFFERSIZE,            
 T_MAXCONNS,
 T_INIT_USER_DATA_FN,
 T_FREE_USER_DATA_FN,
 T_DATA_CALLBACK,
 T_ERROR_CALLBACK
};
                
SERVERINFO * create_server() ;
int set_serverinfo(SERVERINFO *s,int typemask,void *data);
int start(SERVERINFO *s);
int stop(SERVERINFO *s);
int send_data(struct ev_loop *loop,CONN_ITEM *c,void *data,unsigned int len);

#endif
